import axios from "axios";
import router from "../router";
import { Message } from "element-ui";
import { showErrorDetailPop } from "@/utils/common";
import store from "@/store";
export const ip = "api";
export const oss = "/oss"; //nginx代理的文件下载前缀

const service = axios.create({
  // process.env.NODE_ENV === 'development' 来判断是否开发环境
  timeout: 60000,
  baseURL: "/api",
});

service.interceptors.request.use(
  (config) => {
    // var token = localStorage.getItem('token')
    if (store.state.userInfo.token) {
      config.headers.token = store.state.userInfo.token;
    }
    if (store.state.userInfo.orgInfo) {
      const orgInfo = {
        orgId: store.state.userInfo.orgInfo.orgId,
        shortCode: store.state.userInfo.orgInfo.shortCode,
        orgName: store.state.userInfo.orgInfo.orgName,
      };
      config.headers.org = encodeURIComponent(JSON.stringify(orgInfo));
    }
    if (config.method === "post") {
      config.headers["Content-Type"] =
        config.headers["Content-Type"] || "application/json;charset=UTF-8";
    } else {
      config.headers["Content-Type"] =
        config.headers["Content-Type"] || "application/json;charset=UTF-8";
      if (
        Object.prototype.toString.call(config.responseType) ===
        "[object Object]"
      ) {
        config.responseType["Content-Type"] = "application/json;charset=UTF-8";
        config.data = true;
      }
    }
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject("请求错误, 请联系管理员!");
  }
);

/**
 * 使用说明：
 * 成功：then回调，直接取用data即可（无需data.data）
 *      如果是async await方式 直接拿data即可
 * 失败：catch回调（前端调用异常 和 服务端业务异常）
 */
service.interceptors.response.use(
  (response) => {
    if (!response) {
      return;
    }
    // 文件流
    if (response.config.responseType === "arraybuffer") {
      return response.data;
    }
    // excel
    if (
      response.headers["content-type"] &&
      response.headers["content-type"].indexOf("application/vnd.ms-excel") !==
        -1
    ) {
      return response.data;
    }
    const {
      data: { code, data, message },
    } = response;
    // 图片
    if (response.config.responseType == "blob") {
      //blob验证码图片 直接返回数据
      return response.data;
    }

    if (code == 200) {
      // console.log('接口调用成功! url=' + config.url + '\n接口数据:', data)
      const res = !data && (data !== 0 || data !== "0") ? response.data : data;
      return res;
    } else if (response.data.status === "1") {
      // console.log(
      //     '接口调用成功! url=' + config.url + '\n接口数据:',
      //     response.data
      // )
      return response.data.geocodes || response.data.regeocode;
    } else {
      // console.log(
      //     '接口调用失败! url=' + config.url + '\n失败信息:' + message
      // )
      //业务 如果是需要忽略error处理
      try {
        if (response && response.config && response.config.isIgnoreError) {
          //nothing to do
          console.log("忽略业务error处理");
        } else {
          dealErr(code, message);
        }
      } catch (e) {
        console.log(e);
        dealErr(code, message);
      }

      //返回服务器数据{code message data}
      return Promise.reject(response.data);
    }
  },
  (error) => {
    //前端请求err
    console.log("请求失败", error);

    let errorInfo = error.response;
    if (!(typeof errorInfo === undefined) && errorInfo) {
      const { statusText, status, config } = JSON.parse(
        JSON.stringify(error.response)
      );
      const data = { code: status, msg: statusText };
      console.error(
        "接口调用失败! url=" + config.url + "\n失败信息:" + statusText
      );
      dealErr(data.code, data.msg);
    } else {
      dealErr(400, "网络出现问题，请稍后再试");
    }
    //返回前端请求异常数据
    return Promise.reject(error);
  }
);

/**
 * 前端异常和服务器端业务异常处理
 */
let isOpenError = null;
function dealErr(c, message) {
  switch (c) {
    case 400:
      Message.error(message);
      break;
    case 401:
      // 登录超时
      Message.error("登录超时, 请重新登录!");
      window.localStorage.clear();
      window.sessionStorage.clear();
      router.push({ path: "/login" });
      break;
    // 404请求不存在
    case 404:
      Message.error("网络请求不存在");
      break;
    // 其他错误，直接抛出错误提示
    case 405:
      Message.error("请检查未填的非空项");
      break;
    // 其他错误，直接抛出错误提示
    default:
      if (message && !isOpenError) {
        showErrorDetailPop(message);
        // isOpenError = MessageBox({
        //     title: '错误提示',
        //     type: 'error',
        //     message,
        //     customClass: 'request_err_pop',
        //     callback () {
        //         isOpenError = null
        //         console.log('MessageBox callback: ', isOpenError)
        //     }
        // })
      }
  }
}

/**
 * post表单请求方式
 */
service.httpPostForm = function httpPostForm({
  url,
  params = {},
  headers = { "Content-Type": "multipart/form-data" },
  timeout = 60000,
  isLoading = false,
  isIgnoreError = false,
}) {
  const formdata = new FormData();
  for (const p in params) {
    formdata.append(p, params[p]);
  }

  return service.post(url, formdata, {
    headers,
    timeout,
    withCredentials: true,
    isLoading,
    isIgnoreError,
  });
};

/**
 * post请求方式
 */
service.httpPost = function httpPost({
  url,
  params = {},
  headers = {},
  responseType = {},
  isLoading = false,
  isIgnoreError = false,
}) {
  return service.post(url, params, {
    headers,
    withCredentials: true,
    isLoading,
    responseType,
    isIgnoreError,
  });
};

/**
 * get表单请求方式
 */
service.httpGet = function httpGet({
  url,
  params = {},
  headers = {},
  responseType = {},
  isLoading = false,
  isIgnoreError = false,
}) {
  return service.get(url, {
    headers,
    params,
    withCredentials: true,
    responseType,
    isLoading,
    isIgnoreError,
  });
};

/**
 * get表单请求方式
 */
const httpGetFile = function httpGet({
  url,
  params = {},
  headers = {},
  responseType = "arraybuffer",
  isLoading = false,
  isIgnoreError = false,
}) {
  return service.get(url, {
    headers,
    params,
    withCredentials: true,
    responseType,
    isLoading,
    isIgnoreError,
    baseURL: "",
  });
};
service.httpGetFile = httpGetFile;

export default service;
export { httpGetFile };
